//
// Created by keep on 17-10-30.
//
#include <bits/unique_ptr.h>
#include "config.h"
#include "inc.h"
#include "json/json.h"

extern string g_dev_name;
extern string g_server_addr;
extern string g_server_url;
extern string g_station_id;
extern string g_term_id;

bool init_config()
{

    string config_data;
    int ret = get_config_all(config_data);
    if(ret != 0){
        dzlog_error("get config file failed:%d", ret);
        return false;
    }
    dzlog_info("current config:\n%s", config_data.c_str());
    Json::Value root;
    Json::CharReaderBuilder rbuilder;
    std::string errs;
    istringstream in;
    in.str(config_data);
    try {
        bool parsingSuccessful = Json::parseFromStream(rbuilder, in, &root, &errs);
        if (!parsingSuccessful) {
            dzlog_error("Failed to parse configuration");
            return false;
        } else {
            g_server_addr = root.get("server", "").asString();
            if(g_server_addr.length() == 0){
                dzlog_error("error server addr");
                return false;
            }

            dzlog_info("Server Addr:%s", g_server_addr.c_str());
            char server_url[64] = {0};
            sprintf(server_url,"http://%s/iETC/ipc/trans", g_server_addr.c_str());
            g_server_url = server_url;

            int stationid = root.get("stationid", 111111).asInt();
            char tmp_buf[8];
            memset(tmp_buf, 0, 8);
            sprintf(tmp_buf,"%06d", stationid);
            string station_id = tmp_buf;

            int laneid = root.get("laneid", 99).asInt();
            char tmp_buf2[4];
            memset(tmp_buf2, 0, 4);
            sprintf(tmp_buf2,"%02d", laneid);
            string lane_id = tmp_buf2;

            g_station_id = station_id+lane_id;
            g_term_id = root.get("termno","00000000000000000000000000000000").asString();
            dzlog_info("Server Url:%s\nStation Id:%s\nTermNo:%s", g_server_url.c_str(), g_station_id.c_str(), g_term_id.c_str());
        }
    }catch (Json::Exception &exception){
        dzlog_error("cfg json error:%s", exception.what());
        return false;
    }

    //test
//    string test_config_data = "{\"stationid\":100100,\"lanetype\":3,\"laneid\":88,\"termno\":\"92345678123456781234567812345678\",\"bak\":\"\"}";
//    update_config_all(test_config_data);

    return true;
}

int get_config_all(string &out_cfg_data)
{

    FILE *fp = fopen("./itc.cfg", "r");
    if(fp == nullptr){
        dzlog_error("init config error");
        return -1;
    }
    char read_buff[512] = {0};
    size_t  nread = fread(read_buff, sizeof(char), 510, fp);
    if(nread > 0){
        out_cfg_data = read_buff;
    }else{
        dzlog_error("read config file error:%d",errno);
        fclose(fp);
        return -4;
    }

    fclose(fp);
    return 0;
}

int update_config_all(string &config_data)
{
    Json::Value root;
    Json::CharReaderBuilder rbuilder;
    std::string errs;
    istringstream in;
    in.str(config_data);
    dzlog_info("===============(S)Update Config File================");
    try {
        bool parsingSuccessful = Json::parseFromStream(rbuilder, in, &root, &errs);
        if (!parsingSuccessful) {
            dzlog_error("Failed to parse configuration");
            return false;
        } else {
            root["server"] = g_server_addr;

            Json::StreamWriterBuilder builder;
            builder.settings_["indentation"] = "";
            std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());

            ostringstream out_json;
            writer->write(root, &out_json);
            config_data = out_json.str();
        }
    }catch (Json::Exception &exception){
        dzlog_error("cfg json error:%s", exception.what());
        return false;
    }
    dzlog_info("to update config file:\n%s", config_data.c_str());
    FILE *fp = fopen("./itc.cfg", "w+");
    if(fp == nullptr){
        dzlog_error("init config error");
        return -1;
    }
    size_t data_len = config_data.length();
    size_t nwrite = fwrite(config_data.c_str(), sizeof(char), data_len, fp);
    if(nwrite == data_len){
        dzlog_info("update config file success");
    }else{
        dzlog_error("update config file error:%d",errno);
        fclose(fp);
        return -2;
    }
    fclose(fp);
    dzlog_info("===============(E)Update Config File================");
    return 0;
}